/**
 * @file lv_demo_music_list.c
 * 歌曲列表组件
 */

/*********************
 *      INCLUDE
 *********************/
//导入库

//导入自定义头文件
#include "lv_demo_music_list.h"
#include "lv_demo_music_font.h"  // 添加字体头文件
#include "lv_demo_music_main.h"

/**********************
 *  STATIC PROTOTYPES
 **********************/
static lv_obj_t * add_list_btn(lv_obj_t * parent, uint32_t track_id);  // 添加列表按钮
static void btn_click_event_cb(lv_event_t * e);  // 按钮点击事件回调

/**********************
 *  STATIC VARIABLES
 **********************/
static lv_obj_t * list;                    // 歌曲列表对象
static lv_style_t style_scrollbar;         // 滚动条样式
static lv_style_t style_btn;               // 按钮默认样式
static lv_style_t style_btn_pr;            // 按钮按下状态样式
static lv_style_t style_btn_chk;           // 按钮选中状态样式
static lv_style_t style_btn_dis;           // 按钮禁用状态样式
static lv_style_t style_title;             // 歌曲标题样式
static lv_style_t style_artist;            // 艺术家名称样式
static lv_style_t style_time;              // 时间显示样式
static lv_style_t style_sport;              // 运动显示样式


// 声明图像资源
LV_IMG_DECLARE(img_lv_demo_music_btn_list_play);   // 播放按钮图像
LV_IMG_DECLARE(img_lv_demo_music_btn_list_pause);  // 暂停按钮图像


/**********************
 *   GLOBAL FUNCTIONS
 **********************/
/**
 * @brief 创建音乐歌曲列表界面
 * @param parent 父对象
 * @return 创建的列表对象
 *
 * 此函数创建完整的歌曲列表界面，包括：
 * - 初始化各种样式（字体、颜色、布局等）
 * - 创建滚动容器
 * - 添加所有歌曲条目
 * - 设置滚动特性
 */
lv_obj_t * _lv_demo_music_list_create(lv_obj_t * parent)
{
    // 根据屏幕尺寸选择字体大小
#if LV_DEMO_MUSIC_LARGE
    font_small = &ShiYuan_black_Normal_16;   // 大屏小字体
    font_large = &ShiYuan_black_Normal_22;  // 大屏中字体
#else
    font_small = &ShiYuan_black_Normal_12;   // 小屏小字体
    font_large = &ShiYuan_black_Normal_16;  // 小屏中字体
#endif

    /* ========== 初始化各种样式 ========== */

    // 初始化滚动条样式
    lv_style_init(&style_scrollbar);
    lv_style_set_width(&style_scrollbar,  4);                          // 设置滚动条宽度
    lv_style_set_bg_opa(&style_scrollbar, LV_OPA_COVER);               // 设置不透明度
    lv_style_set_bg_color(&style_scrollbar, lv_color_hex3(0xeee));     // 设置浅灰色背景
    lv_style_set_radius(&style_scrollbar, LV_RADIUS_CIRCLE);           // 设置圆形半径
    lv_style_set_pad_right(&style_scrollbar, 4);                       // 设置右边距

    // 定义网格布局列和行配置
    static const lv_coord_t grid_cols[] = {LV_GRID_CONTENT, LV_GRID_FR(1), LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
#if LV_DEMO_MUSIC_LARGE
    static const lv_coord_t grid_rows[] = {35,  30, LV_GRID_TEMPLATE_LAST};  // 大屏行高
#else
    static const lv_coord_t grid_rows[] = {22,  17, LV_GRID_TEMPLATE_LAST};  // 小屏行高
#endif

    // 初始化按钮默认样式
    lv_style_init(&style_btn);
    lv_style_set_bg_opa(&style_btn, LV_OPA_TRANSP);                    // 透明背景
    lv_style_set_grid_column_dsc_array(&style_btn, grid_cols);         // 设置网格列
    lv_style_set_grid_row_dsc_array(&style_btn, grid_rows);            // 设置网格行
    lv_style_set_grid_row_align(&style_btn, LV_GRID_ALIGN_CENTER);     // 行居中对齐
    lv_style_set_layout(&style_btn, LV_LAYOUT_GRID);                   // 使用网格布局
    //lv_style_set_bg_color(&style_btn,  lv_color_hex(0x4c4965));     // 深紫色背景
#if LV_DEMO_MUSIC_LARGE
    lv_style_set_pad_right(&style_btn, 30);                            // 大屏右边距
#else
    lv_style_set_pad_right(&style_btn, 20);                            // 小屏右边距
#endif

    // 初始化按钮按下状态样式
    lv_style_init(&style_btn_pr);
    lv_style_set_bg_opa(&style_btn_pr, LV_OPA_COVER);                  // 不透明背景
    lv_style_set_bg_color(&style_btn_pr,  lv_color_hex(0x4c4965));     // 深紫色背景

    // 初始化按钮选中状态样式
    lv_style_init(&style_btn_chk);
    lv_style_set_bg_opa(&style_btn_chk, LV_OPA_COVER);                 // 不透明背景
    lv_style_set_bg_color(&style_btn_chk, lv_color_hex(0x4c4965));     // 深紫色背景

    // 初始化按钮禁用状态样式
    lv_style_init(&style_btn_dis);
    lv_style_set_text_opa(&style_btn_dis, LV_OPA_40);                  // 文字40%透明度
    lv_style_set_img_opa(&style_btn_dis, LV_OPA_40);                   // 图像40%透明度

    // 初始化歌曲标题样式
    lv_style_init(&style_title);
    lv_style_set_text_font(&style_title, font_large);                 // 中字体
    lv_style_set_text_color(&style_title, lv_color_hex(0xffffff));     // 白色文字

    // 初始化艺术家名称样式
    lv_style_init(&style_artist);
    lv_style_set_text_font(&style_artist, font_small);                 // 小字体
    lv_style_set_text_color(&style_artist,lv_color_hex(0xb1b0be));     // 浅灰色文字

    // 初始化时间显示样式
    lv_style_init(&style_time);
    lv_style_set_text_font(&style_time, font_large);                  // 中字体
    lv_style_set_text_color(&style_time, lv_color_hex(0xffffff));      // 白色文字

    // 初始化运动状态名称样式
    lv_style_init(&style_sport);
    lv_style_set_text_font(&style_sport, font_small);                 // 小字体
    lv_style_set_text_color(&style_sport,lv_color_hex(0xb1b0be));     // 浅灰色文字

    /* ========== 创建列表容器 ========== */
    // 创建透明的列表容器
    list = lv_obj_create(parent);
    lv_obj_remove_style_all(list);                                     // 移除所有默认样式
    lv_obj_set_size(list, LV_HOR_RES, LV_VER_RES - LV_DEMO_MUSIC_HANDLE_SIZE); // 设置尺寸
    lv_obj_set_y(list, LV_DEMO_MUSIC_HANDLE_SIZE);                     // 设置Y坐标
    lv_obj_add_style(list, &style_scrollbar, LV_PART_SCROLLBAR);       // 添加滚动条样式
    lv_obj_set_flex_flow(list, LV_FLEX_FLOW_COLUMN);                   // 设置垂直流式布局

    // 循环添加所有歌曲按钮到列表
    uint32_t track_id;
    for(track_id = 0; _lv_demo_music_get_title(track_id); track_id++) {
        add_list_btn(list, track_id);
    }

    // 设置滚动对齐特性（方形或圆形屏幕）
#if LV_DEMO_MUSIC_SQUARE || LV_DEMO_MUSIC_ROUND
    lv_obj_set_scroll_snap_y(list, LV_SCROLL_SNAP_CENTER);  // 设置垂直滚动居中对齐
#endif

    // 默认选中第一首歌曲
    _lv_demo_music_list_btn_check(0, true);

    return list;
}

/**
 * @brief 设置歌曲列表按钮的选中状态
 * @param track_id 歌曲ID
 * @param state 选中状态（true为选中，false为未选中）
 *
 * 此函数更新指定歌曲按钮的视觉状态：
 * - 选中状态显示暂停图标
 * - 未选中状态显示播放图标
 * - 自动滚动到选中的项目
 */
void _lv_demo_music_list_btn_check(uint32_t track_id, bool state)
{
    lv_obj_t * btn = lv_obj_get_child(list, track_id);    // 获取指定ID的按钮
    lv_obj_t * icon = lv_obj_get_child(btn, 0);           // 获取按钮中的图标

    if(state) {
        lv_obj_add_state(btn, LV_STATE_CHECKED);          // 添加选中状态
        lv_img_set_src(icon, &img_lv_demo_music_btn_list_pause);  // 设置为暂停图标
        lv_obj_scroll_to_view(btn, LV_ANIM_ON);           // 滚动到可见区域
    }
    else {
        lv_obj_clear_state(btn, LV_STATE_CHECKED);        // 清除选中状态
        lv_img_set_src(icon, &img_lv_demo_music_btn_list_play);   // 设置为播放图标
    }
}

/**********************
 *   STATRIC FUNCTIONS
 **********************/

/**
 * @brief 添加单个歌曲按钮到列表
 * @param parent 父对象（列表容器）
 * @param track_id 歌曲ID
 * @return 创建的按钮对象
 *
 * 此函数创建单个歌曲条目，包含：
 * - 播放/暂停图标
 * - 歌曲标题
 * - 艺术家名称
 * - 歌曲时长
 * - 底部边框
 */
static lv_obj_t * add_list_btn(lv_obj_t * parent, uint32_t track_id)
{
    // 获取歌曲信息
    uint32_t t = _lv_demo_music_get_track_length(track_id);  // 歌曲时长（秒）
    char time[32];
    lv_snprintf(time, sizeof(time), "%"LV_PRIu32":%02"LV_PRIu32, t / 60, t % 60);  // 格式化为"分:秒"
    const char * title = _lv_demo_music_get_title(track_id);    // 歌曲标题
    const char * artist = _lv_demo_music_get_artist(track_id);  // 艺术家名称
    const char * condition = condition_list[track_id];  // 运动状态

    // 创建按钮
    lv_obj_t * btn = lv_obj_create(parent);
    lv_obj_remove_style_all(btn);  // 移除所有默认样式

    // 设置按钮尺寸
#if LV_DEMO_MUSIC_LARGE
    lv_obj_set_size(btn, lv_pct(100), 110);  // 大屏高度
#else
    lv_obj_set_size(btn, lv_pct(100), 60);   // 小屏高度
#endif

    // 添加各种样式到按钮
    lv_obj_add_style(btn, &style_btn, 0);                // 默认样式
    lv_obj_add_style(btn, &style_btn_pr, LV_STATE_PRESSED);     // 按下状态样式
    lv_obj_add_style(btn, &style_btn_chk, LV_STATE_CHECKED);    // 选中状态样式
    lv_obj_add_style(btn, &style_btn_dis, LV_STATE_DISABLED);   // 禁用状态样式
    lv_obj_add_event_cb(btn, btn_click_event_cb, LV_EVENT_CLICKED, NULL);  // 点击事件


    /* ========== 创建按钮内的子组件 ========== */

    // 创建播放/暂停图标
    lv_obj_t * icon = lv_img_create(btn);
    lv_img_set_src(icon, &img_lv_demo_music_btn_list_play);  // 默认播放图标
    lv_obj_set_grid_cell(icon, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_CENTER, 0, 2);  // 网格定位

    // 创建歌曲标题标签
    lv_obj_t * title_label = lv_label_create(btn);
    lv_label_set_text(title_label, title);  // 设置标题文本
    lv_obj_set_grid_cell(title_label, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1);  // 网格定位
    lv_obj_add_style(title_label, &style_title, 0);  // 应用标题样式

    // 创建水平容器来放置运动状态和艺术家标签
    lv_obj_t * hor_cont_artist = lv_obj_create(btn);
    lv_obj_remove_style_all(hor_cont_artist);
    lv_obj_set_size(hor_cont_artist, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
    lv_obj_set_flex_flow(hor_cont_artist, LV_FLEX_FLOW_ROW);  // 水平布局
    lv_obj_set_flex_align(hor_cont_artist, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    lv_obj_set_style_pad_all(hor_cont_artist, 0, 0);
    lv_obj_set_style_bg_opa(hor_cont_artist, LV_OPA_0, 0);  // 透明背景

    // 将水平容器放置在网格的(1,1)位置
    lv_obj_set_grid_cell(hor_cont_artist, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 1, 1);
    lv_obj_set_style_pad_top(hor_cont_artist, 2, 0);

    // 创建运动状态标签
    lv_obj_t * condition_list_label = lv_label_create(hor_cont_artist);
    lv_label_set_text(condition_list_label, condition);  // 设置运动状态文本
    lv_obj_add_style(condition_list_label, &style_sport, 0);  // 应用艺术家样式

    // 添加分隔符
    lv_obj_t * separator = lv_label_create(hor_cont_artist);
    lv_label_set_text(separator, " | ");
    lv_obj_add_style(separator, &style_artist, 0);  // 使用相同的样式
    lv_obj_set_style_pad_hor(separator, 8, 0);  // 左右间距

    // 创建艺术家名称标签
    lv_obj_t * artist_label = lv_label_create(hor_cont_artist);
    lv_label_set_text(artist_label, artist);  // 设置艺术家文本
    lv_obj_add_style(artist_label, &style_artist, 0);  // 应用艺术家样式

    // 创建时长标签
    lv_obj_t * time_label = lv_label_create(btn);
    lv_label_set_text(time_label, time);  // 设置时长文本
    lv_obj_add_style(time_label, &style_time, 0);  // 应用时间样式
    lv_obj_set_grid_cell(time_label, LV_GRID_ALIGN_END, 2, 1, LV_GRID_ALIGN_CENTER, 0, 2);  // 网格定位，右对齐

    // 声明并创建底部边框图像
    LV_IMG_DECLARE(img_lv_demo_music_list_border);
    lv_obj_t * border = lv_img_create(btn);
    lv_img_set_src(border, &img_lv_demo_music_list_border);  // 设置边框图像
    lv_obj_set_width(border, lv_pct(120));                   // 设置宽度为120%
    lv_obj_align(border, LV_ALIGN_BOTTOM_MID, 0, 0);         // 底部居中对齐
    lv_obj_add_flag(border, LV_OBJ_FLAG_IGNORE_LAYOUT);      // 忽略布局计算

    return btn;
}

/**
 * @brief 歌曲按钮点击事件回调函数
 * @param e 事件对象
 *
 * 当用户点击歌曲列表中的按钮时，播放对应的歌曲
 */
static void btn_click_event_cb(lv_event_t * e)
{
    lv_obj_t * btn = lv_event_get_target(e);        // 获取被点击的按钮

    uint32_t idx = lv_obj_get_index(btn);        // 获取按钮在列表中的索引

    _lv_demo_music_play(idx);                       // 播放对应索引的歌曲
}
